package com.gitee.neuray.security.admin.menu.biz;

import com.alibaba.fastjson.JSONObject;
import com.gitee.neuray.security.admin.element.biz.AdminElementBiz;
import com.gitee.neuray.security.admin.element.entity.AdminElementEntity;
import com.gitee.neuray.security.admin.menu.vo.AdminMenuVo;
import com.gitee.neuray.security.admin.vo.AdminElement;
import com.gitee.neuray.security.common.exception.BaseException;
import com.gitee.neuray.security.common.msg.TableResultResponse;
import com.gitee.neuray.security.common.util.Query;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.common.Mapper;
import com.gitee.neuray.security.common.biz.BaseBiz;

import com.gitee.neuray.security.admin.menu.mapper.AdminMenuMapper;
import com.gitee.neuray.security.admin.menu.entity.AdminMenuEntity;
import tk.mybatis.mapper.entity.Example;


@Service
@Transactional(rollbackFor = Exception.class)
public class AdminMenuBiz extends BaseBiz<AdminMenuMapper,AdminMenuEntity> {
    @Autowired
    private AdminElementBiz adminElementBiz;

    @Override
    protected String getPageName() {
        return "AdminMenu"+"Biz";
    }

    //建立树形结构
    public List<AdminMenuEntity> buildTree(){
        List<AdminMenuEntity> treeMenus =new ArrayList<AdminMenuEntity>();

        Map<String,List<AdminMenuEntity>> map = getRootNode();

        List<AdminMenuEntity> rootList = map.get("rootList");

        for(AdminMenuEntity menuNode : rootList) {
            menuNode=buildChilTree(menuNode,map.get("menuList"));
            treeMenus.add(menuNode);
        }
        return treeMenus;
    }

    //递归，建立子树形结构
    private AdminMenuEntity buildChilTree(AdminMenuEntity pNode,List<AdminMenuEntity> menuList){
        List<AdminMenuEntity> chilMenus =new  ArrayList<AdminMenuEntity>();
        for(AdminMenuEntity menuNode : menuList) {
            if(menuNode.getParentId().equals(pNode.getId())) {
                chilMenus.add(buildChilTree(menuNode,menuList));
            }
        }
        pNode.setChildren(chilMenus);
        return pNode;
    }

    //获取根节点
    private Map<String,List<AdminMenuEntity>> getRootNode() {

        List<AdminMenuEntity> menuList = mapper.selectAll();

        List<AdminMenuEntity> rootMenuLists =new  ArrayList<AdminMenuEntity>();
        for(AdminMenuEntity menuNode : menuList) {
            if(menuNode.getParentId().equals("root")) {
                rootMenuLists.add(menuNode);
            }
        }

        Map<String,List<AdminMenuEntity>> ret = new HashMap<>();

        ret.put("menuList",menuList);
        ret.put("rootList",rootMenuLists);

        return ret;
    }

    /**
     * 分页获取信息（启用）
     * @param query
     * @return
     */
    public TableResultResponse<AdminMenuEntity> page(Query query,AdminMenuEntity adminMenuEntity){

        String id = adminMenuEntity.getId();

        Page<Object> result = PageHelper.startPage(query.getPageNo(), query.getPageSize());
        Example example = new Example(AdminMenuEntity.class);

        //设置条件，当menuId不为空时候，查询当前id以及parentId为当前id的下一级菜单
        if(id != null && !id.isEmpty()){
            Example.Criteria criteria = example.createCriteria();
            criteria.orEqualTo("parentId",id).orEqualTo("id",id);
        }

        List<AdminMenuEntity> list = mapper.selectByExample(example);
        return new TableResultResponse<AdminMenuEntity>(result.getPageSize(),result.getPageNum(),result.getPages(),result.getTotal(),list);
    }

    public AdminMenuVo getMenu(String menuId){
        if(StringUtils.isEmpty(menuId)){
            throw new BaseException("菜单id不能为空...");
        }
        AdminMenuEntity adminMenuEntity = selectById(menuId);
        if(adminMenuEntity == null){
            throw new BaseException("数据库中不存在的菜单...");
        }
        AdminElementEntity adminElementEntity = new AdminElementEntity();
        adminElementEntity.setMenuId(menuId);
        List<AdminElementEntity> adminElementEntities = adminElementBiz.selectList(adminElementEntity);
        List<Map<String,String>> elements = new ArrayList<>();
        adminElementEntities.stream().forEach(entity ->{
            Map map = new HashMap();
            map.put("code",entity.getCode());
            map.put("method",entity.getMethod());
            map.put("name",entity.getName());
            elements.add(map);
        });
        AdminMenuVo adminMenuVo = JSONObject.parseObject(JSONObject.toJSONString(adminMenuEntity), AdminMenuVo.class);

        adminMenuVo.setElements(elements);
        return adminMenuVo;
    }

    /**
     * 修改菜单
     * @param adminMenuVo
     */
    public void updateMenuAndElements(AdminMenuVo adminMenuVo){
        AdminMenuEntity adminMenuEntity = JSONObject.parseObject(JSONObject.toJSONString(adminMenuVo),AdminMenuEntity.class);
        if(StringUtils.isEmpty(adminMenuEntity.getId())){
            throw new BaseException("主键不能为空...");
        }
        //修改菜单信息
        updateSelectiveById(adminMenuEntity);
        List<Map<String,String>> elements = adminMenuVo.getElements();
        insertElements(adminMenuVo.getId(),elements);
    }

    /**
     * 添加菜单，同时添加按钮
     * @param adminMenuVo
     */
    public void insertMenuAndElements(AdminMenuVo adminMenuVo) {
        AdminMenuEntity adminMenuEntity = JSONObject.parseObject(JSONObject.toJSONString(adminMenuVo),AdminMenuEntity.class);
        //添加菜单基本信息
        insertSelective(adminMenuEntity);
        //添加按钮
        List<Map<String,String>> elements = adminMenuVo.getElements();
        insertElements(adminMenuVo.getId(),elements);
    }
    private void insertElements(String menuid,List<Map<String,String>> elements){
        //删除菜单的element再增加
        AdminElementEntity temp = new AdminElementEntity();
        temp.setMenuId(menuid);
        if(!StringUtils.isEmpty(menuid)){
            adminElementBiz.delete(temp);
        }
        //添加
        elements.stream().forEach(method ->{
            adminElementBiz.insertSelective(getAdminElement(menuid,method));
        });
    }
    private AdminElementEntity getAdminElement(String menuId,Map<String,String> elements){
        AdminElementEntity adminElement = new AdminElementEntity();
        adminElement.setMenuId(menuId);
        adminElement.setMethod(elements.get("method"));
        adminElement.setCode(elements.get("code"));
        adminElement.setName(elements.get("name"));
        return adminElement;
    }
}
